package picobot.rule;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import picobot.interfaces.core.IRule;
import picobot.interfaces.core.IRuleBuilder;

/**
 * a class to build a rule
 */
public class RuleBuilder implements IRuleBuilder {

	private final static String LINE_SEPERATOR = System
			.getProperty("line.separator");

	@Override
	public IRule parseRule(String ruleString) {

		int requiredState = 0, targetState = 0;
		String destination = null;

		// create substrings
		String[] ruleParts = new String[5];
		ruleParts = ruleString.split(" ");

		requiredState = Integer.parseInt(ruleParts[0]);
		String surroundings = ruleParts[1];
		String direction = ruleParts[3];
		targetState = Integer.parseInt(ruleParts[4]);

		String[] environment = new String[4];

		try {

			// first check for walls in every direction
			if (surroundings.charAt(0) == 'N') {
				environment[0] = "WALL";
			}

			if (surroundings.charAt(1) == 'E') {
				environment[1] = "WALL";
			}

			if (surroundings.charAt(2) == 'W') {
				environment[2] = "WALL";
			}

			if (surroundings.charAt(3) == 'S') {
				environment[3] = "WALL";
			}

			// then check for anything else
			for (int i = 0; i < 4; i++) {

				switch (surroundings.charAt(i)) {

				case 'x':
					environment[i] = "FREE";
					break;
				case '*':
					environment[i] = "ANY";
					break;
				}
			}

			// extract destination:
			switch (direction.charAt(0)) {
			case 'N':
				destination = "NORTH";
				break;
			case 'E':
				destination = "EAST";
				break;
			case 'W':
				destination = "WEST";
				break;
			case 'S':
				destination = "SOUTH";
				break;
			case 'X':
				destination = "STAY";
				break;
			}

		} catch (NullPointerException e) {
			System.err.println("Your rule has the wrong format: "
					+ e.getMessage());
		}

		IRule newRule = new Rule(requiredState, environment, destination,
				targetState);
		return newRule;
	}

	@Override
	public List<IRule> parseRules(String srule) {
		List<IRule> someRules = new ArrayList<IRule>();
		String[] lines = srule.split(LINE_SEPERATOR);

		try {
			for (int i = 0; i < lines.length; i++) {
				if (!(lines[i].isEmpty())) {
					if (!(lines[i].charAt(0) == ' ')) {
						someRules.add(parseRule(lines[i]));
					}
				}
			}
		} catch (NullPointerException e) {
			System.err.println("Some of your rules are wrong formated:"
					+ e.getMessage());
		}

		return someRules;
	}

	@Override
	public List<IRule> parseRules(File ruleFile) {

		StringBuilder sb = new StringBuilder();

		try {
			BufferedReader br = new BufferedReader(new FileReader(ruleFile));
			String content;

			while ((content = br.readLine()) != null) {
				sb.append(content + System.getProperty("line.separator"));

			}
			br.close();

		} catch (IOException e) {
			e.printStackTrace();
		}

		return this.parseRules(sb.toString());
	}

}
